package histogram;

import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

public class MakeHistogram {

//    String origin = "2_20k.jpg";
    String origin = "6_20k.jpg";
//    String marked = "marked histogram.bmp";
    String marked = "marked 6_20.bmp";
//    String tempimage = "lipid.bmp";
    String resultFile = "6_20 60 10.txt";
    BufferedImage rootOrigin = null;
    BufferedImage rootMarked = null;
//    BufferedImage rootTemp = null;

    int window = 60;
    int windOffset = 10;
    
    public MakeHistogram() {
        loadImage();

        countHistogram();

    }

    void loadImage() {
        try {
//            rootTemp = ImageIO.read(new File(tempimage));
            rootOrigin = ImageIO.read(new File(origin));
            rootMarked = ImageIO.read(new File(marked));
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
    }

  

    void countHistogram() {
        FileWriter fout = null;
        try {
            fout = new FileWriter(resultFile);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        int width = rootMarked.getWidth();
        int height = rootMarked.getHeight();
        System.out.println(width + " " + height);

        int[][] originMatrix = new int[width][height];
        int[][] typeMatrix = new int[width][height];

//        [0, 255, 255, 0]      mitahColor
//        [255, 175, 175, 0]    lipidColor

        int mitColor[] = {0, 255, 255, 0};
        int lipidColor[] = {255, 175, 175, 0};

        final int TYPE_MITAH = 1;   
        final int TYPE_LIPID = 2;
        final int TYPE_BACK = 3;

        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {

                Raster colorMarked = rootMarked.getRaster();
                int sampleMar[] = new int[4];
                colorMarked.getPixel(i, j, sampleMar);
                Raster colorUnMarked = rootOrigin.getRaster();
                int sampleUnMark[] = new int[4];
                colorUnMarked.getPixel(i, j, sampleUnMark);

                if (Arrays.equals(sampleMar, mitColor)) {
                    typeMatrix[i][j] = TYPE_MITAH;
                    originMatrix[i][j] = sampleUnMark[1];
                } else if (Arrays.equals(sampleMar, lipidColor)) {
                    typeMatrix[i][j] = TYPE_LIPID;
                    originMatrix[i][j] = sampleUnMark[1];
                } else {
                    typeMatrix[i][j] = TYPE_BACK;
                    originMatrix[i][j] = sampleUnMark[1];
                }
            }
        }

        final double EDGE = 0;
        final double MITAH = 1;
        final double LIPID = 2;
        final double BACK = 3;
        int count = 0;
        for (int xSt = 0; xSt < width - window; xSt += windOffset) {
            for (int ySt = 0; ySt < height - window; ySt += windOffset) {

                boolean isBack = false;
                boolean isLipid = false;
                boolean isMitah = false;

                int bins = 64;
                int binVals[] = new int[bins];
                Arrays.fill(binVals, 0);
                double mark = 0;

                int mit = 0;
                int lip = 0;
                int back = 0;

                for (int i = xSt; i < xSt + window; i++) {
                    for (int j = ySt; j < ySt + window; j++) {

                        if (typeMatrix[i][j] == TYPE_MITAH) {
                            isMitah = true;
                            mit++;
                        } else if (typeMatrix[i][j] == TYPE_LIPID) {
                            isLipid = true;
                            lip++;
                        } else {
                            back++;
                            isBack = true;
                        }

                        int val = originMatrix[i][j];
                        binVals[val / 4]++;
                    }
                }

                int sq = window * window;
                double mitRatio = mit * 1.0 / sq;
                double lipRatio = lip * 1.0 / sq;
                double backRatio = back * 1.0 / sq;
                double thresh = 0.75;

                if (backRatio > thresh) {
                    mark = BACK;
                } else if (lipRatio > thresh) {
                    mark = LIPID;
                } else if (mitRatio > thresh) {
                    mark = MITAH;
                } else {
                    mark = EDGE;
                }

//                if ((isLipid || isMitah) && isBack && mitRatio<thresh && lipRatio<thresh) {
//                    mark = EDGE;
//                } else if (isLipid) {
//                    mark = LIPID;
//                } else if (isMitah) {
//                    mark = MITAH;
//                } else {
//                    mark = BACK;
//                }

                try {
                    fout.write(xSt + " " + ySt + " ");
                    for (int i = 0; i < bins; i++) {
                        fout.write(binVals[i]+" ");
//                        System.out.print(binVals[i] + " ");
                    }
//                    System.out.println("");
                    fout.write(mark + "");
//                    System.out.println(mark);
                    fout.write(System.lineSeparator());
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
                count++;
//                System.out.println("new line added");
            }
        }
        System.out.println("count = " + count);
        try {
            fout.close();
            System.out.println("file is closed");
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }

    }
}
